package com.singfan.common.db.provider;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.singfan.common.SingFanException;
import com.singfan.common.db.config.Database;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于C3P0的数据库连接池提供类
 * Author: HanSongHe
 * Date: 15-7-11 上午11:35
 */
public class C3p0ConnectionPoolProvider extends ConnectionPoolProvider {
    private Map<String, ComboPooledDataSource> dataSourceMap = new HashMap<>();
    private Map<String, Boolean> readMap = new HashMap<>();
    private Map<String, Boolean> writeMap = new HashMap<>();
    @Override
    public void init(List<Database> databaseList) {
        try {
            for(Database database : databaseList){
                ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
                comboPooledDataSource.setUser(database.getUser());
                comboPooledDataSource.setPassword(database.getPassword());
                comboPooledDataSource.setJdbcUrl(database.getDbUrl());
                comboPooledDataSource.setDriverClass(database.getDbDriverClass());
                comboPooledDataSource.setMaxStatements(100);
                comboPooledDataSource.setMaxIdleTime(60);
                comboPooledDataSource.setInitialPoolSize(database.getInitialPoolSize());
                comboPooledDataSource.setMinPoolSize(database.getMinPoolSize());
                comboPooledDataSource.setMaxPoolSize(database.getMaxPoolSize());

                dataSourceMap.put(database.getId(), comboPooledDataSource);

                readMap.put(database.getId(), database.isRead());
                writeMap.put(database.getId(), database.isWrite());
            }
        }
        catch (PropertyVetoException pve){
            throw new SingFanException(String.format("C3p0ConnectionPoolProvider.initPool() error: %s !", pve.getMessage()), pve);
        }
    }

    @Override
    public Connection getConnection(String databaseId) {
        try {
            ComboPooledDataSource dataSource = dataSourceMap.get(databaseId);
            if(dataSource != null){
                return dataSource.getConnection();
            }
            else {
                throw new SingFanException(String.format("C3p0ConnectionPoolProvider.getConnection() error: can not get DataSource from databaseId(%s)", databaseId));
            }
        }
        catch (SQLException e) {
            throw new SingFanException(String.format("C3p0ConnectionPoolProvider.getConnection(databaseId=%1s) error: %2s", databaseId, e.getMessage()), e);
        }
    }

    @Override
    public boolean read(String databaseId) {
        return readMap.get(databaseId);
    }

    @Override
    public boolean write(String databaseId) {
        return writeMap.get(databaseId);
    }
}
